package com.example.goods_manage.interceptor;

import com.example.goods_manage.commons.enums.TokenEnum;
import com.example.goods_manage.dto.User;
import com.example.goods_manage.mapper.UserMapper;
import com.example.goods_manage.utils.AjaxResult;
import com.example.goods_manage.utils.HttpStatus;
import com.example.goods_manage.utils.JWTUtil;
import com.example.goods_manage.utils.UserThreadLocalUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * <P> Description: 拦截除开 /user/* 下的请求
 * 校验token 是否携带
 * 如果没有携带，不允许访问
 * 如果携带了，需要验证是否有效
 * 如果有效，则需要保存用户信息，方便后面的方法调用
 */
@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private UserMapper userMapper;

    /**
     * 调用controller之前执行代码
     * 返回值true 表示放行 false表示拦截
     * 拦截器会拦截哪些请求:普通请求、静态资源
     **/
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //放行 OPTIONS 请求
        if (request.getMethod().equals(RequestMethod.OPTIONS.name())) {
            return true;
        }
        String token = getToken(request);
        log.info("获取到token:{}", token);
        if (token == null ||
                token.length() == 0 ||
                "null".equals(token) ||
                !JWTUtil.verify(token).equals((TokenEnum.TOKEN_SUCCESS))) {

            response.setContentType("application/json;charset=utf-8");

            String data = new ObjectMapper()
                    .writeValueAsString
                            (AjaxResult.error(HttpStatus.SEE_OTHER, "token 异常 重新登录"));
            log.info("token异常 需要重定向:{}", token);
            response.getWriter().write(data);
            return false;
        }
        Integer uid = JWTUtil.getUid(token);
        User user = userMapper.findUserById(uid);
        UserThreadLocalUtils.setUser(user);
        return true;
    }

    /**
     * 令牌自定义标识
     */
    public static final String HEADER = "Authorization";
    /**
     * 令牌前缀
     */
    public static final String TOKEN_PREFIX = "Bearer ";

    /**
     * 获取请求token
     */
    public String getToken(HttpServletRequest request) {
        String token = request.getHeader(HEADER);
        if (!StringUtils.isEmpty(token) && token.startsWith(TOKEN_PREFIX)) {
            token = token.replace(TOKEN_PREFIX, "");
        }
        return token;
    }
}
